<template>
  <view id="drawerContent" class="drawer-container" :style="{
      maxHeight: `calc(100vh - ${ windowHeight } - ${ excessHeight })`,
      height: touchModule.drawerContentHeight,
      minHeight
    }">
    <view
      class="top"
      @touchend.stop="touchModule.handleDragSideEnd"
      @touchmove.stop="touchModule.handleDragSideMove"
      @touchstart.stop="touchModule.handleDragSideStart">
      <view :class="['dot', touchModule.isTouchActive && 'dot-active']"></view>
    </view>

    <view class="header">
      <slot name="header"></slot>
    </view>
    <view :class="[styleModule.name]">
      <slot name="content"></slot>
    </view>
  </view>
</template>

<script setup lang="ts">
  import {
    ref,
    onMounted,
    getCurrentInstance,
    reactive,
    defineEmits,
    defineProps,
    useCssModule
  } from "vue";

  const props = defineProps({
    height: {
      type: String,
      default: '40rem'
    },
    minHeight: {
      type: String,
      default: '15rem'
    },
    swiperStyle: {
      type: Boolean,
      default: false
    },
    excessHeight: {
      type: String,
      default: '0rem'
    }
  });

  const windowHeight = ref(getApp().globalData!.pageTop);

  let query: UniApp.SelectorQuery | null = null;

  const emit = defineEmits(['update:height']);

  /**
   * 容器样式模块
   */
  const styleModule = reactive({
    name: '',
    init() {
      const module: any = useCssModule('content');
      props.swiperStyle ? (this.name = module['swiper-container']) : (this.name = module['base-container'])
    }
  });

  /*用户操作模块*/
  const touchModule = reactive({
    pageY: 0,
    isTouchActive: false,
    drawerContentHeight: props.height,
    drawerContentDomHeight: 0,
    handleDragSideStart: function (e: any) {
      this.isTouchActive = true;
      query?.select('#drawerContent').boundingClientRect((data) => {
        this.pageY = e.changedTouches[0].clientY;
        this.drawerContentDomHeight = (data as UniApp.NodeInfo).height as number;
      }).exec();
    },
    handleDragSideEnd: function () {
      this.isTouchActive = false;
    },
    handleDragSideMove: function(e: any) {
      let height: number;
      if (e.changedTouches[0].clientY > this.pageY) {
        height = this.drawerContentDomHeight - (e.changedTouches[0].clientY - this.pageY)
      } else {
        height = this.drawerContentDomHeight + (this.pageY - e.changedTouches[0].clientY);
      }
      this.drawerContentHeight = height + 'px';
      emit('update:height', height + 'px');
    }
  });

  onMounted(() => {
    query = uni.createSelectorQuery().in(getCurrentInstance());
    styleModule.init();
  });

</script>

<style scoped lang="scss">
  .drawer-container {
    width: 37.5rem;
    position: fixed;
    left: 50%;
    bottom: 0;
    z-index: 3;
    transform: translateX(-50%) scaleX(1.01);
    border-top: 2px solid $uni-text-color;
    border-right: 2px solid $uni-text-color;
    border-left: 2px solid $uni-text-color;
    border-top-left-radius: 2.5rem;
    border-top-right-radius: 2.5rem;
    background-color: #fff;
    display: flex;
    flex-direction: column;
    box-sizing: border-box;

    .top {
      height: 2.5rem;
      display: flex;
      justify-content: center;
      box-sizing: border-box;
      padding-top: 0.8rem;

      .dot {
        height: 0.5rem;
        width: 3.6rem;
        background-color: #F9EEDC;
        border-radius: 0.25rem;
        transition: background-color .2s;

        &.dot-active {
          background-color: $uni-text-color;
        }
      }
    }

    .header {
      padding: 0 2rem 0 2rem;
      margin-bottom: 1.8rem;
    }
  }
</style>
<style lang="scss" module="content">
  .base {
    box-sizing: border-box;
    padding: 0 2rem 0 2rem;
    flex: 1;
  }

  .base-container {
    @extend .base;
    overflow-y: auto;

    &::-webkit-scrollbar {
      display: none;
      width: 0;
      height: 0;
      color: transparent;
    }
  }

  .swiper-container {
    @extend .base;
    padding: 0;
  }
</style>